package iteratormodule;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * @author by 何坤
 * @Classname TestIterator02
 * @Description TODO
 * @Date 2019/10/17 11:09
 */
public class TestIterator02 {

    private static final List<Integer> INTEGER_LIST = Arrays.asList(0,0,1,0,2,0,4,0,3);

    public static void main(String[] args) {
        foreachRemove01(INTEGER_LIST);
        foreachRemove02(INTEGER_LIST);
        foreachRemove03(INTEGER_LIST);
    }

    /**
     * 这种方式虽然不会报错，但是删不干净，因为当删除第一个0时，
     * 由于list变小，且循环变量i加1，所以第2个元素会在遍历时无法取到删除。
     * @param
     * @param list
     * @return void
     * @date 2019/10/17 11:34
     * @author 何坤
     */
    private static void foreachRemove01(List<Integer> list){
        List<Integer> lists = new ArrayList<>(list);
        for (int i = 0; i < lists.size(); i++){
            if (lists.get(i) == 0){
                lists.remove(i);
            }
        }
        lists.stream().forEach(System.out::println);
    }

    /**
     * 这种方法会在运行时抛出java.util.ConcurrentModificationException异常。
     * 这是因为ForEach内部使用的迭代器不允许当一个线程在迭代集合时，另一个线程
     * 来修改这个集合。这样会造成迭代的不稳定。所以抛出异常。
     * @param
     * @param list
     * @return void
     * @date 2019/10/17 11:35
     * @author 何坤
     */
    private static void foreachRemove02(List<Integer> list){
        List<Integer> lists = new ArrayList<>(list);
        for (Integer i : lists){
            if (i == 0){
                lists.remove(i);
            }
        }
        lists.stream().forEach(System.out::println);
    }

    /**  
     * 该方法正确，每调用一次iterator.next()方法，只能调用一次remove()方法。
     * 调用remove()方法前，必须调用过一次next()方法。
     * iterator.remove()方法：从迭代器指向的集合中移除迭代器返回的最后一个元素（可选操作）。
     *      每次调用 next 只能调用一次此方法。如果进行迭代时用调用此方法之外的其他方式修改
     *      了该迭代器所指向的集合，则迭代器的行为是不明确的。
     *      抛出：
     *      UnsupportedOperationExceptio - 如果迭代器不支持 remove 操作。
     *      IllegalStateException - 如果尚未调用 next 方法，或者在上一次调用next 方法之后已经调用了remove 方法。
     * @param 
     * @param list
     * @return void
     * @date 2019/10/17 11:38
     * @author 何坤
     */       
    private static void foreachRemove03(List<Integer> list){
        List<Integer> lists = new ArrayList<>(list);
        Iterator<Integer> it = lists.iterator();
        while(it.hasNext()){
            if (0 == it.next()){
                it.remove();
            }
        }
        lists.stream().forEach(System.out::println);
    }
}
